package com.callbell.cas.handler.api;

import com.alibaba.fastjson.JSONObject;
import com.callbell.cas.util.Digests;
import com.callbell.cas.util.Encodes;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha512Hash;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * api接口
 */
@SuppressWarnings("deprecation")
public class ApiController extends AbstractController{
	
	private JdbcTemplate jdbcTemplate;

    private static final int HASH_INTERATIONS = 264544;
	
	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {

        String mtype = ServletRequestUtils.getStringParameter(request, "mtype");
        String params = ServletRequestUtils.getStringParameter(request, "params");
        JSONObject paramsJson = (JSONObject) JSONObject.parse(params);
        String result = "{\"status\":0,\"msg\":\"mtype param is incorrect\"}";
        if ("register".equals(mtype)) {
            result = register(paramsJson).toString();
        } else if ("query".equals(mtype)) {
            result = query(paramsJson).toString();
        }
        response.getWriter().write(result);
        return null;

	}


    /**
     * 查询
     */
    private JSONObject query(JSONObject params) throws ServletRequestBindingException {
        String mobilePhone = params.getString("mobilePhone");
        List list = jdbcTemplate.queryForList("SELECT * FROM user WHERE account = ?", mobilePhone);
//        Map<String,String> maptemp = new HashMap<String, String>();
//        if (cot == 1){
//            maptemp.put("status","0");
//            maptemp.put("msg","该手机号码已经存在");
//        }else{
//            maptemp.put("status","1");
//            maptemp.put("msg","该手机号码可用");
//        }
//        net.sf.json.JSONObject jsonObject = net.sf.json.JSONObject.fromObject(maptemp);
//        System.out.println(jsonObject);
//        return jsonObject;

        JSONObject result = new JSONObject();
        if (list.size() == 1){
            result.put("status","0");
            result.put("msg","mobilePhone has exist");
        }else if(list.size() > 1){
            result.put("status","2");
            result.put("msg","mobilePhone has exception！");
        }else{
            result.put("status","1");
            result.put("msg","mobilePhone is ok to use!");

        }

        return result;

    }
    /**
     *  注册
     */
	private JSONObject register(JSONObject params) throws ServletRequestBindingException {
        JSONObject result = new JSONObject();
        if (params == null){
            result.put("status", 0);
            result.put("msg", "params is null");
            return result;
        }
        final String account = params.getString("account");
        if (StringUtils.isBlank(account)){
            result.put("status", 0);
            result.put("msg", "account is null");
            return result;
        }
        int userId = 0;
        boolean userExsits = true;
        String password = null;
        List<Map<String, Object>> user = jdbcTemplate.queryForList("SELECT * FROM user WHERE account = ? LIMIT 1", account);
        if (user == null || user.size() == 0){
            userExsits = false;
            password = params.getString("password");
            if (StringUtils.isBlank(password)){
                result.put("status", 0);
                result.put("msg", "password is null");
                return result;
            }
        } else {
            userId = Integer.valueOf(user.get(0).get("user_id").toString());
        }

        String openId = params.getString("open_id");
        if (StringUtils.isBlank(openId)){
            result.put("status", 0);
            result.put("msg", "open_id is null");
            return result;
        }
        Integer userType = params.getInteger("user_type");
        if (userType == null){
            result.put("status", 0);
            result.put("msg", "user_type is null");
            return result;
        }

        boolean openIdExists = false;
        List<Map<String, Object>> tum = jdbcTemplate.queryForList("SELECT * FROM third_user_map WHERE open_id = ? AND user_type = ?", openId, userType);
        if (tum != null && tum.size() > 0){
            openIdExists = true;
            result.put("status", 0);
            result.put("msg", "open_id is existing");
            return result;
        }

        if (!userExsits){
            byte[] bsalt = Digests.generateSalt(32);
            final String salt = Encodes.encodeHex(bsalt);
            Sha512Hash sha = new Sha512Hash(password, bsalt, HASH_INTERATIONS);
            final String saltPassword = sha.toHex();
            GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
            int count = jdbcTemplate.update(new PreparedStatementCreator() {
                @Override
                public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
                    PreparedStatement ps = con.prepareStatement("INSERT INTO user(account, mobile, password, salt, create_time) VALUES(?,?,?,?,NOW())", Statement.RETURN_GENERATED_KEYS);
                    ps.setString(1, account);
                    ps.setString(2, account);
                    ps.setString(3, saltPassword);
                    ps.setString(4, salt);
                    return ps;
                }
            }, keyHolder);
            if (count == 0){
                result.put("status", 0);
                result.put("msg", "user insert error");
                return result;
            }
            Number key = keyHolder.getKey();
            if (key != null){
                userId = key.intValue();
                jdbcTemplate.update("INSERT INTO user_map_role(user_id,role_id,create_time,statue) VALUES(?,?,NOW(),?)", userId, 1, 1);
            }
        }
        if (!openIdExists){
            int count = jdbcTemplate.update("INSERT INTO third_user_map (open_id,user_id,cellphone,user_type,create_time) VALUES (?,?,?,?,NOW())", openId, userId, account, userType);
            if (count == 0){
                result.put("status", 0);
                result.put("msg", "third info insert error");
                return result;
            }
        }
        result.put("status", 1);
        return result;
    }

	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}


}
